package user_controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	cons2 "shimmer/neusoft_club_backend/controllers/cons"
	"shimmer/neusoft_club_backend/controllers/user_controller/application"
	"shimmer/neusoft_club_backend/controllers/user_controller/club"
	"shimmer/neusoft_club_backend/controllers/utils"
	"shimmer/neusoft_club_backend/dao/domain"
	"shimmer/neusoft_club_backend/middlewares/auth_middleware"
	"shimmer/neusoft_club_backend/services"
	"shimmer/neusoft_club_backend/services/actor_service"
	"shimmer/neusoft_club_backend/services/club_service"
	"shimmer/neusoft_club_backend/services/errs"
	"shimmer/neusoft_club_backend/services/user_service"
	"strconv"
)

// @Summary 查询用户信息
// @Description 通过用户的ID查找用户信息
// @Tags 用户
// @accept json
// @Produce json
// @Param userID path integer true "name"
// @Success 200 {object} domain.UserDTO
// @Router /api/user/single/{userID} [get]
func getUserInfoByID(c *gin.Context) {
	id, err := strconv.ParseInt(c.Param(cons2.UserUriParam), 10, 64)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	user, err := user_service.FindUserByID(id)
	if err != nil {
		services.AbortWithDatabaseError(c, err)
		return
	}
	c.JSON(http.StatusOK, user)
}

func removeUserByID(c *gin.Context) {
	id, err := strconv.ParseInt(c.Param(cons2.UserUriParam), 10, 64)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	err = user_service.DeleteUserByID(id)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.AbortWithStatus(http.StatusNoContent)
}

// @Summary 获取自己的所有职位
// @Description
// @Tags 用户
// @accept json
// @Produce json
// @Param page query integer false "页面"
// @Param size query integer true "页码"
// @Success 200 {object} domain.ClubPositionDTO
// @Router /api/user/self/position [get]
func getSelfPositions(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	pageQuery, err := utils.GetPaginationFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	positions, err := club_service.GetUsersUserStruct(user.ID, pageQuery)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, positions)
}

// @Summary 获取自己的所有部门
// @Description
// @Tags 用户
// @accept json
// @Produce json
// @Param page query integer false "页面"
// @Param size query integer true "页码"
// @Success 200 {object} domain.ClubDepartmentStructDTO
// @Router /api/user/self/department [get]
func getSelfDepartments(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	pageQuery, err := utils.GetPaginationFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	departments, err := club_service.GetUsersDepartments(user.ID, pageQuery)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, departments)

}

// @Summary 获取自己的所有角色信息
// @Description
// @Tags 用户
// @Param page query integer false "page"
// @Param size query integer true "size"
// @Param club_id query integer false "社团ID"
// @Param actor_type query integer false "角色类型 1:成员 2:社长 4:管理员"
// @Success 200 {object} []domain.UserActorDTO
// @Router /api/user/self/role [get]
func findAllUserRoles(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}

	pageQuery, err := utils.GetPaginationFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}

	query := &actor_service.FindActorQuery{}

	if err = c.ShouldBindQuery(query); err != nil {
		services.AbortWithError(c, err)
		return
	}

	res, err := actor_service.FindActorWithQuery(user.ID, query, pageQuery)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, res)
}

type checkUserActorStatusRes struct {
	Student bool `json:"student"`
	Leader  bool `json:"leader"`
	Admin   bool `json:"admin"`
}

// @Summary 检查角色信息
// @Description
// @Tags 用户
// @Success 200 {object} checkUserActorStatusRes
// @Router /api/user/self/role/check [get]
func checkUserActorStatus(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	actors := []domain.AuthorizationRole{
		domain.AuthStudent,
		domain.AuthLeader,
		domain.AuthAdmin,
	}
	resMap := make(map[string]bool, 3)
	for _, actor := range actors {
		res, err := actor_service.FindActorWithQuery(user.ID, &actor_service.FindActorQuery{
			ActorType: &actor,
		}, &utils.PaginationQuery{
			Page: 0,
			Size: 10,
		})
		if err != nil {
			services.AbortWithError(c, err)
			return
		}
		resMap[domain.AuthKeyValue[actor]] = res.TotalCount > 0
	}
	c.JSON(http.StatusOK, resMap)
}

// @Summary 更新用户信息
// @Description
// @Tags 用户
// @Param info body user_service.UpdateUserInfoMutation true "用户信息"
// @Success 204
// @Router /api/user/self [put]
func updateSelfInfo(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	mutation := &user_service.UpdateUserInfoMutation{}
	if err = c.ShouldBind(mutation); err != nil {
		services.AbortWithError(c, err)
		return
	}
	if err = user_service.UpdateUser(user.ID, mutation); err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.AbortWithStatus(http.StatusNoContent)

}

// @Summary 添加权限
// @Description
// @Tags 用户
// @Param userID query integer true "被添加权限的用户ID"
// @Param club_id query integer false "社团ID"
// @Param role query integer true "权限"
// @Success 204
// @Router /api/user/single/{userID}/role [post]
func addUserRole(c *gin.Context) {
	panic("need implemented")
}

// @Summary 删除权限
// @Description
// @Tags 用户
// @Param userID query integer true "用户ID"
// @Param club_id query integer false "社团ID"
// @Param role query integer true "权限"
// @Success 204
// @Router /api/user/single/{userID}/role [delete]
func removeUserRole(c *gin.Context) {
	panic("need implemented")
}
// @Summary 查找所有用户
// @Description
// @Tags 用户
// @Param page query integer false "页面"
// @Param size query integer true "页面大小"
// @Success 200 {object} []domain.UserDTO
// @Router /api/user [get]
func findAllUsers(c *gin.Context) {
	user,err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	isAdmin,err := club_service.CheckIsAdmin(user.ID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !isAdmin {
		services.AbortWithError(c, errs.ErrNotAdmin)
		return
	}
	pageQuery, err := utils.GetPaginationFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	res,err := user_service.FindAllUser(map[string]interface{}{},pageQuery)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK,res)
}
type searchUserReq struct {
	Where map[string]interface{} `json:"where" form:"where" binding:"-"`
}
// @Summary 查找用户
// @Description
// @Tags 用户
// @Param page query integer false "页面"
// @Param size query integer true "页面大小"
// @Param value body user_controller.searchUserReq true "参数"
// @Success 200 {object} []domain.UserDTO
// @Router /api/user/search [post]
func searchUser(c *gin.Context) {
	user,err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	isAdmin,err := club_service.CheckIsAdmin(user.ID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !isAdmin {
		services.AbortWithError(c, errs.ErrNotAdmin)
		return
	}
	pageQuery, err := utils.GetPaginationFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	req := &searchUserReq{}
	if err = c.ShouldBind(req);err != nil {
		services.AbortWithError(c, err)
		return
	}
	res,err := user_service.FindAllUser(req.Where,pageQuery)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK,res)
}

func ConfigureUserController(r *gin.RouterGroup) {
	{
		clubGroup := r.Group("/self/club", auth_middleware.AuthLoginMiddleware())
		club.ConfigureUserClubController(clubGroup)
	}
	{
		userApplicationGroup := r.Group("/self/application", auth_middleware.AuthLoginMiddleware())
		application.ConfigureUserApplicationController(userApplicationGroup)
	}
	r.GET("/",auth_middleware.AuthLoginMiddleware(),findAllUsers)
	r.POST("/search",auth_middleware.AuthLoginMiddleware(),searchUser)
	r.GET(fmt.Sprintf("/single/:%s", cons2.UserUriParam), getUserInfoByID)
	r.DELETE(fmt.Sprintf("/single/:%s", cons2.UserUriParam), auth_middleware.AuthRolesMiddleware(domain.AuthAdmin), removeUserByID)
	r.POST(fmt.Sprintf("/single/:%s/role", cons2.UserUriParam), auth_middleware.AuthLoginMiddleware(), addUserRole)
	r.DELETE(fmt.Sprintf("/single/:%s/role", cons2.UserUriParam), auth_middleware.AuthLoginMiddleware())
	r.GET("/self/position", auth_middleware.AuthLoginMiddleware(), getSelfPositions)
	r.GET("/self/department", auth_middleware.AuthLoginMiddleware(), getSelfDepartments)
	r.GET("/self/role", auth_middleware.AuthLoginMiddleware(), findAllUserRoles)
	r.PUT("/self", auth_middleware.AuthLoginMiddleware(), updateSelfInfo)
	r.GET("/self/role/check", auth_middleware.AuthLoginMiddleware(), checkUserActorStatus)

}
